One of the side effects of adding mod support into the game engine is that we had to build a cross-platform dynamic/shared library loader. This is enabled by the UntitledRuntimeLibraryLoader which we developed. To include it use:
#include <urll/urll.h>All the functions under the URLL namespace named and
work like in Unix, so they can feel familiar to use. There are also 2
utility functions for ease of use.
Functions
dlopen- returns avoid*handle given a path to the library*dlerror- returns achar*with the latest errordlclose- closes the library given the handle**dlsym- retrieves a symbol from the library given a name
* Due to Windows restrictions dlopen cannot receive a
flag and will always default to lazy loading
** dlclose closes the library handle, which makes all
the memory acquired from dlsym null
dlsym
There are currently 3 definitions of dlsym, all of them
take a handle and a name
- Standard
dlsymthat returns avoid*and only takes a handle and a name std::functionvariant that assigns thevoid*fromdlsymto anstd::function- The templated variant, which casts the
void*to the specified template type
Here are some examples:
dlsym with std::function
std::function<void(void)> func;
// We check against nullptr or the handle for errors
if (URLL::dlsym(handle, "func", func) == nullptr)
{
return -1;
}
func();dlsym with a templated type
void(*func)(void);
// We check against nullptr or the handle for errors
if (URLL::dlsym(handle, "func", func) == nullptr)
{
return -1;
}
func();regular dlsym
int* a = (int*)URLL::dlsym(handle, "func", func);
// We check against nullptr or the handle for errors
if (a == nullptr)
{
return -1;
}
std::cout << *a << std::endl;Example of full URLL usage
This is an extract from the auto-generated main file for the modded executable
#ifdef _WIN32
void* handle = URLL::dlopen("Modlib.dll");
#else
// That https://madladsquad.com/ is required on unix systems
void* handle = URLL::dlopen("https://madladsquad.com/libModlib.so");
#endif
bool bCanClose = false;
if (handle != nullptr)
{
bCanClose = true;
if (URLL::dlsym(handle, "modlibbegin", UVK::global.modbegin) == handle && URLL::dlsym(handle, "modlibend", UVK::global.modend) == handle && URLL::dlsym(handle, "modlibtick", UVK::global.modtick) == handle)
logger.consoleLog("Loaded all mods!", UVK_LOG_TYPE_SUCCESS);
else
logger.consoleLog("Failed to load some or all of the initial mod library functions, mod events will not be loaded! Error: ", UVK_LOG_TYPE_WARNING, URLL::dlerror());
}
else
logger.consoleLog("Failed to load the mod library!", UVK_LOG_TYPE_WARNING);
...
dlclose(handle);- Home
- Beginner concepts
- Advanced concepts
- Engine developer and contributor resources